package com.client.core.file;


import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.*;

/**
 * 文件处理器，用于文件切割功能等
 */
public class FileHandler {




    //拆分大小,请保证拆分大小保证大于1 kB，大小自己控制
    public static int FILESIZE = 1;

    public static void main(String[] args) throws Exception {
        //保存拆分
//        splitFile();
        //进行合并
//        merge();
    }


    /**
     * 拆分文件
     *
     * @param file
     * @param seek
     * @param count
     * @return
     * @throws Exception
     */
    public static byte[] getFiles(RandomAccessFile file, long seek, int count) throws Exception {
        file.seek(seek);
        byte[] bytes = new byte[count];
        file.read(bytes);
        return bytes;
    }


    /**
     * 拆分文件
     *
     * @throws Exception
     */
    public static void splitFile(String filePath) throws Exception {
        File file = new File(filePath);
        if (!file.isFile()) {
            throw new NullPointerException("拆分的文件不是一个文件");
        }

        RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "r");
        FileChannel channel = randomAccessFile.getChannel();
        long size = channel.size();
        long l = size / 1024;
        if (l > FILESIZE) {
            //计算前部整体
            int i;
            String tmpFilePath=file.getAbsolutePath();
            for (i = 0; i < l / FILESIZE; i++) {
                byte[] files = getFiles(randomAccessFile, randomAccessFile.getFilePointer(), FILESIZE * 1024);
                FileOutputStream out = new FileOutputStream(tmpFilePath + "." + (i + 1) + ".tmp");
                out.write(files);
                out.flush();
                out.close();
            }
            //计算尾巴
            long l1 = size - ((size / (FILESIZE * 1024)) * FILESIZE * 1024);
            if (l1 > 0) {
                byte[] files = getFiles(randomAccessFile, randomAccessFile.getFilePointer(), (int) l1);
                FileOutputStream out = new FileOutputStream(tmpFilePath + "." + (i + 1) + ".tmp");
                out.write(files);
                out.flush();
                out.close();
            }
            //生成拆分说明
            FileOutputStream out = new FileOutputStream(tmpFilePath + "拆分说明.tmp");
            //拆分文件名，拆分份数，拆分大小，最后一次拆分大小，被拆分文件总大小
            out.write((file.getName() + "," + (i + 1) + "," + FILESIZE + "," + l1 + "," + size).getBytes());
            out.flush();
            out.close();
            randomAccessFile.close();
        }
    }


    /**
     * 创建一个临时文件用于补充文件
     *
     * @param size
     */
    public static void createBigFile(long size) {
        Path filePath = Paths.get("E:/test/个人简历_new.docx");
        try {
            if (!Files.exists(filePath)) {
                Files.createFile(filePath);
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        ByteBuffer buffer = ByteBuffer.allocate(1);
        try (FileChannel fileChannel = FileChannel.open(filePath, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
            fileChannel.position(size - 1);
            fileChannel.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 合并
     */
    public static void merge(String path) throws Exception {
        FileInputStream inputStream = new FileInputStream(path + "拆分说明.tmp");
        FileChannel channel = inputStream.getChannel();
        byte[] bytes = new byte[(int) channel.size()];
        inputStream.read(bytes);
        String string = new String(bytes);
        String[] split = string.trim().split(",");
        //创建一个空的文件
        createBigFile(Long.parseLong(split[split.length - 1]));
        RandomAccessFile file = new RandomAccessFile(path, "rw");
        for (int i = 0; i < Integer.parseInt(split[1]); i++) {
            System.out.println("拆分合并中---->" + path + "." + (i + 1) + ".tmp");
            FileInputStream fin = new FileInputStream(path + "." + (i + 1) + ".tmp");
            byte[] byt;
            //合并尾部文件
            if (i == Integer.parseInt(split[1]) - 1) {
                byt = new byte[Integer.parseInt(split[3])];
            } else {
                byt = new byte[Integer.parseInt(split[2]) * 1024];
            }
            fin.read(byt);
            file.seek(file.getFilePointer());
            file.write(byt);
        }
        file.close();
    }


    /**
     * 复制
     * @param source
     * @param dest
     * @throws IOException
     */
    public static void copyFile(File source, File dest)
            throws IOException {
        InputStream input = null;
        OutputStream output = null;
        try {
            input = new FileInputStream(source);
            output = new FileOutputStream(dest);
            byte[] buf = new byte[1024];
            int bytesRead;
            while ((bytesRead = input.read(buf)) > 0) {
                output.write(buf, 0, bytesRead);
            }
        } finally {
            input.close();
            output.close();
        }
    }

    /**
     * 删除
     * @param file
     */
    public static void delFile(File file) {
        File[] files = file.listFiles();
        if (files != null && files.length != 0) {
            for (int i = 0;i<files.length;i++) {
                delFile(files[i]);
            }
        }
        file.delete();
    }


    /**
     * 读取 文件
     * @param file
     * @return
     */
    public static String getString(File file) {


        InputStreamReader inputStreamReader = null;

        try {

            InputStream inputStream =new FileInputStream(file);

            inputStreamReader = new InputStreamReader(inputStream, "utf-8");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        BufferedReader reader = new BufferedReader(inputStreamReader);
        StringBuffer sb = new StringBuffer("");
        String line;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            return null;
        }
        return sb.toString();

    }
}
